/*
 * JOCL - Java bindings for OpenCL
 *
 * Copyright 2014 Marco Hutter - http://www.jocl.org/
 */
 
// Originally, this was based on
// https://github.com/l-urence/smith-waterman/blob/master/src/kernel.cl
// but heavily modified
 
#define MATCH 2
#define MISMATCH -1
#define INDEL -1
 
int match(char c0, char c1)
{
    if (c0 == c1)
    {
        return MATCH;
    }
    return MISMATCH;
}
 
 
__kernel void smithWaterman (
    __global int *matrix,  
    int sizeX,
    int sizeY,
    __global int *subIndices,
    int subSize,
    __global char *s0,
    __global char *s1)
{
    int gid = get_global_id(0);
    int startX = subIndices[gid+gid+0];
    int startY = subIndices[gid+gid+1];  
 
    for (int xx = startX; xx < startX + subSize; xx++)
    {
        int x = xx + 1;
        if (x < sizeX)
        {
            for (int yy = startY; yy < startY + subSize; yy++)
            {
                int y = yy + 1;
                if (y < sizeY)
                {
                    int index = x+y*sizeX;
                    int nw = matrix[xx+yy*sizeX] + match(s0[xx], s1[yy]);
                    int n  = matrix[x+ yy*sizeX] + INDEL;
                    int w  = matrix[xx+y *sizeX] + INDEL;
                   
                    int max = 0;
                    max = nw > max ? nw : max;
                    max = n  > max ? n  : max;
                    max = w  > max ? w  : max;
                    matrix[index] = max;
                }
            }
        }
    }
}